﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace ImageCut
{
    public partial class Form1 : Form
    {
        // 成员变量
        private string currentImagePath = "";

        private bool isDrawing = false;
        private Point startPoint;
        private Rectangle currentRect = Rectangle.Empty;
        private Bitmap originalImage = null;       

        // Int32Rect参数
        private int rectX = 0;
        private int rectY = 0;
        private int rectWidth = 0;
        private int rectHeight = 0;

        private List<string> imageFiles = new List<string>();
        private string selectedFolder = "";
        private float imageScale = 1.0f;
        private int imageOffsetX = 0;
        private int imageOffsetY = 0;

        // 批量处理相关
        private CancellationTokenSource cancellationTokenSource;
        private bool isBatchProcessing = false;

        public Form1()
        {
            InitializeComponent();
            // 设置PictureBox的双缓冲以减少闪烁
            typeof(PictureBox).GetProperty("DoubleBuffered",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
                .SetValue(pictureBox1, true, null);
            // 添加事件处理
            pictureBox1.SizeChanged += PictureBox1_SizeChanged;
            pictureBox1.Paint += PictureBox1_Paint;
        }

        // PictureBox大小变化事件处理
        private void PictureBox1_SizeChanged(object sender, EventArgs e)
        {
            if (originalImage != null)
            {
                CalculateImageScaleAndOffset();
                pictureBox1.Invalidate(); // 触发重绘
            }
        }

        // 批量裁剪按钮点击事件
        private async void btnBatchCut_Click(object sender, EventArgs e)
        {
            if (isBatchProcessing)
            {
                MessageBox.Show("批量处理正在进行中，请稍候", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (string.IsNullOrEmpty(selectedFolder) || imageFiles.Count == 0)
            {
                MessageBox.Show("请先选择包含图片的文件夹", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 验证裁剪参数
            if (!int.TryParse(textBox1.Text, out int x) ||
                !int.TryParse(textBox2.Text, out int y) ||
                !int.TryParse(textBox3.Text, out int width) ||
                !int.TryParse(textBox4.Text, out int height))
            {
                MessageBox.Show("请输入有效的裁剪参数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (width <= 0 || height <= 0)
            {
                MessageBox.Show("裁剪宽度和高度必须大于0", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string cutDirectory;
            using (var folderBrowserDialog = new FolderBrowserDialog())
            {
                folderBrowserDialog.Description = "请选择一个目录作为路径：";
                folderBrowserDialog.ShowNewFolderButton = true;

                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    cutDirectory = folderBrowserDialog.SelectedPath;
                }
                else
                {
                    return;
                }
            }

            // 创建取消令牌
            cancellationTokenSource = new CancellationTokenSource();
            isBatchProcessing = true;

            // 显示进度控件
            progressBar1.Visible = true;
            labelProgress.Visible = true;
            btnCancelBatch.Visible = true;
            progressBar1.Maximum = imageFiles.Count;
            progressBar1.Value = 0;

            // 禁用批量裁剪按钮
            btnBatchCut.Enabled = false;
            btnSelectFolder.Enabled = false;

            try
            {
                // 使用封装的ImageCropHelper进行批量裁剪
                var parameters = new ImageCropHelper.CropParameters
                {
                    X = x,
                    Y = y,
                    Width = width,
                    Height = height
                };

                int successCount = 0;
                int failCount = 0;
                int processedCount = 0;
                object lockObj = new object(); // 用于线程同步
                DateTime lastUpdateTime = DateTime.Now;
                
                // 使用字典记录每个文件的处理结果，最后一次性更新ListView
                var processResults = new System.Collections.Concurrent.ConcurrentDictionary<string, (bool Success, string Message)>();

                // 使用分区策略并行处理，避免最后阶段的假停滞
                await Task.Run(async () =>
                {
                    try
                    {
                        // 计算线程数和分区大小
                        int threadCount = Environment.ProcessorCount;
                        int totalFiles = imageFiles.Count;
                        int partitionSize = (int)Math.Ceiling((double)totalFiles / threadCount);

                        // 创建任务列表
                        List<Task> tasks = new List<Task>();

                        // 按分区创建任务，每个任务处理固定范围的文件
                        for (int i = 0; i < threadCount; i++)
                        {
                            int startIndex = i * partitionSize;
                            if (startIndex >= totalFiles) break;

                            int endIndex = Math.Min(startIndex + partitionSize, totalFiles);

                            // 为每个分区创建独立任务
                            var task = Task.Run(() =>
                            {
                                // 处理当前分区的所有文件
                                for (int j = startIndex; j < endIndex; j++)
                                {
                                    // 检查取消标志
                                    if (cancellationTokenSource.Token.IsCancellationRequested)
                                        break;

                                    string filePath = imageFiles[j];

                                    // 执行裁剪
                                    var result = ImageCropHelper.CropImage(filePath, parameters, cutDirectory);

                                    // 线程安全地更新计数器
                                    lock (lockObj)
                                    {
                                        processedCount++;
                                        if (result.Success)
                                            successCount++;
                                        else
                                            failCount++;

                                        int currentProcessed = processedCount;
                                        int currentSuccess = successCount;
                                        int currentFail = failCount;

                                        // 每处理2个文件或每50ms更新一次进度条（提升更新频率）
                                        bool shouldUpdate = (currentProcessed % 2 == 0) || 
                                                           (currentProcessed == imageFiles.Count) ||
                                                           ((DateTime.Now - lastUpdateTime).TotalMilliseconds > 50);

                                        if (shouldUpdate)
                                        {
                                            lastUpdateTime = DateTime.Now;
                                            
                                            // 使用BeginInvoke异步更新进度（不阻塞）
                                            this.BeginInvoke(new Action(() =>
                                            {
                                                progressBar1.Value = currentProcessed;
                                                labelProgress.Text = $"处理进度：{currentProcessed}/{imageFiles.Count} (成功:{currentSuccess} 失败:{currentFail})";
                                            }));
                                        }
                                    }

                                    // 记录处理结果，最后一次性更新ListView
                                    processResults[filePath] = result.Success 
                                        ? (true, result.Parameters.ToString()) 
                                        : (false, result.ErrorMessage);
                                }
                            }, cancellationTokenSource.Token);

                            tasks.Add(task);
                        }

                // 等待所有分区任务完成 - 使用异步等待避免阻塞
                        await Task.WhenAll(tasks);
                    }
                    catch (OperationCanceledException)
                    {
                        // 用户取消操作，正常退出
                    }
                }, cancellationTokenSource.Token);
                
                // 一次性批量更新ListView所有项目的状态
                this.BeginInvoke(new Action(() =>
                {
                    listView1.BeginUpdate(); // 暂停绘制，提升性能
                    
                    foreach (ListViewItem item in listView1.Items)
                    {
                        string filePath = item.SubItems[1].Text;
                        if (processResults.TryGetValue(filePath, out var result))
                        {
                            // 只更新状态列和参数列
                            item.SubItems[2].Text = result.Success ? "已处理" : "处理失败";
                            item.SubItems[3].Text = result.Message;
                        }
                    }
                    
                    listView1.EndUpdate(); // 恢复绘制
                    
                    // 最后更新一次UI确保数据准确
                    progressBar1.Value = processedCount;
                    labelProgress.Text = $"处理进度：{processedCount}/{imageFiles.Count} (成功:{successCount} 失败:{failCount})";
                }));

                // 显示结果
                if (cancellationTokenSource.Token.IsCancellationRequested)
                {
                    MessageBox.Show($"批量裁剪已取消！已处理: {successCount + failCount}/{imageFiles.Count}\n成功: {successCount}, 失败: {failCount}",
                        "批量处理结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show($"批量裁剪完成！成功: {successCount}, 失败: {failCount}",
                        "批量处理结果", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("批量裁剪出错: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复界面状态
                isBatchProcessing = false;
                progressBar1.Visible = false;
                labelProgress.Visible = false;
                btnCancelBatch.Visible = false;
                btnBatchCut.Enabled = true;
                btnSelectFolder.Enabled = true;

                // 释放取消令牌
                cancellationTokenSource?.Dispose();
                cancellationTokenSource = null;
            }
        }

        // 取消批量处理
        private void btnCancelBatch_Click(object sender, EventArgs e)
        {
            if (cancellationTokenSource != null && !cancellationTokenSource.Token.IsCancellationRequested)
            {
                cancellationTokenSource.Cancel();
                btnCancelBatch.Enabled = false;
                btnCancelBatch.Text = "取消中...";
            }
        }

        // 选择文件夹按钮点击事件
        private void btnSelectFolder_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
            {
                folderDialog.Description = "选择包含图片的文件夹";
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    selectedFolder = folderDialog.SelectedPath;
                    LoadImageFiles(selectedFolder);
                }
            }
        }

        // ListView选中项变更事件
        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                string selectedFilePath = listView1.SelectedItems[0].SubItems[1].Text;
                try
                {
                    currentImagePath = selectedFilePath;
                    originalImage = new Bitmap(currentImagePath);
                    pictureBox1.Image = (Bitmap)originalImage.Clone();

                    // 计算缩放比例和偏移量
                    CalculateImageScaleAndOffset();

                    // 重置矩形参数
                    ResetRectangle();

                    // 加载已保存的参数
                    string param = listView1.SelectedItems[0].SubItems[3].Text;
                    if (!string.IsNullOrEmpty(param) && param.StartsWith("(") && param.EndsWith(")") && param.Contains(","))
                    {
                        string[] parts = param.Trim('(', ')').Split(',');
                        if (parts.Length == 4)
                        {
                            textBox1.Text = parts[0];
                            textBox2.Text = parts[1];
                            textBox3.Text = parts[2];
                            textBox4.Text = parts[3];

                            // 更新矩形参数
                            if (int.TryParse(parts[0], out int x) &&
                                int.TryParse(parts[1], out int y) &&
                                int.TryParse(parts[2], out int w) &&
                                int.TryParse(parts[3], out int h))
                            {
                                rectX = x;
                                rectY = y;
                                rectWidth = w;
                                rectHeight = h;
                                currentRect = new Rectangle(x, y, w, h);
                                DrawRectangleOnImage();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("加载图片失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // 记录截图参数按钮点击事件
        private void btnRecord_Click(object sender, EventArgs e)
        {
            // 更新文本框显示当前矩形参数
            textBox1.Text = rectX.ToString();
            textBox2.Text = rectY.ToString();
            textBox3.Text = rectWidth.ToString();
            textBox4.Text = rectHeight.ToString();
        }

        // 裁剪按钮点击事件
        private void btnCut_Click(object sender, EventArgs e)
        {
            if (originalImage == null)
            {
                MessageBox.Show("请先打开图片", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 尝试从文本框读取参数，如果失败则使用当前记录的参数
            try
            {
                rectX = string.IsNullOrEmpty(textBox1.Text) ? rectX : int.Parse(textBox1.Text);
                rectY = string.IsNullOrEmpty(textBox2.Text) ? rectY : int.Parse(textBox2.Text);
                rectWidth = string.IsNullOrEmpty(textBox3.Text) ? rectWidth : int.Parse(textBox3.Text);
                rectHeight = string.IsNullOrEmpty(textBox4.Text) ? rectHeight : int.Parse(textBox4.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("参数格式错误: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 选择保存目录
            string cutDirectory;
            using (var folderBrowserDialog = new FolderBrowserDialog())
            {
                folderBrowserDialog.Description = "请选择一个目录作为路径：";
                folderBrowserDialog.ShowNewFolderButton = true;

                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    cutDirectory = folderBrowserDialog.SelectedPath;
                }
                else
                {
                    return;
                }
            }

            try
            {
                // 使用封装的ImageCropHelper进行裁剪
                var parameters = new ImageCropHelper.CropParameters
                {
                    X = rectX,
                    Y = rectY,
                    Width = rectWidth,
                    Height = rectHeight
                };

                var result = ImageCropHelper.CropImage(currentImagePath, parameters, cutDirectory);

                if (result.Success)
                {
                    // 在PictureBox中显示裁剪后的图像
                    using (Bitmap croppedImage = new Bitmap(result.SavedFilePath))
                    {
                        pictureBox1.Image = (Bitmap)croppedImage.Clone();
                    }

                    // 更新ListView状态
                    UpdateListViewItem(currentImagePath, "已处理", result.Parameters.ToString());

                    MessageBox.Show($"图片已成功裁剪并保存为: {result.SavedFilePath}", "成功", 
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("裁剪图片失败: " + result.ErrorMessage, "错误", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("裁剪图片失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 计算图片缩放比例和偏移量
        private void CalculateImageScaleAndOffset()
        {
            if (originalImage == null || pictureBox1.Width == 0 || pictureBox1.Height == 0)
            {
                imageScale = 1.0f;
                imageOffsetX = 0;
                imageOffsetY = 0;
                return;
            }

            // 计算缩放比例
            float scaleX = (float)pictureBox1.Width / originalImage.Width;
            float scaleY = (float)pictureBox1.Height / originalImage.Height;
            imageScale = Math.Min(scaleX, scaleY);

            // 计算偏移量（居中显示时）
            float displayWidth = originalImage.Width * imageScale;
            float displayHeight = originalImage.Height * imageScale;
            imageOffsetX = (int)((pictureBox1.Width - displayWidth) / 2);
            imageOffsetY = (int)((pictureBox1.Height - displayHeight) / 2);
        }

        // 鼠标按下事件
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image == null)
                return;

            if (e.Button == MouseButtons.Left)
            {
                isDrawing = true;
                // 将鼠标坐标转换为图片实际坐标
                startPoint = new Point(
                    (int)((e.X - imageOffsetX) / imageScale),
                    (int)((e.Y - imageOffsetY) / imageScale)
                );
                currentRect = Rectangle.Empty;
            }
        }

        // 鼠标移动事件
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDrawing && pictureBox1.Image != null)
            {
                // 将鼠标坐标转换为图片实际坐标
                Point currentPoint = new Point(
                    (int)((e.X - imageOffsetX) / imageScale),
                    (int)((e.Y - imageOffsetY) / imageScale)
                );

                // 计算当前矩形
                int x = Math.Min(startPoint.X, currentPoint.X);
                int y = Math.Min(startPoint.Y, currentPoint.Y);
                int width = Math.Abs(startPoint.X - currentPoint.X);
                int height = Math.Abs(startPoint.Y - currentPoint.Y);

                currentRect = new Rectangle(x, y, width, height);

                // 重绘PictureBox
                DrawRectangleOnImage();
            }
        }

        // 鼠标释放事件
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (isDrawing && pictureBox1.Image != null)
            {
                isDrawing = false;

                // 保存矩形参数
                if (currentRect.Width > 0 && currentRect.Height > 0)
                {
                    rectX = currentRect.X;
                    rectY = currentRect.Y;
                    rectWidth = currentRect.Width;
                    rectHeight = currentRect.Height;
                }

                // 重绘最终矩形
                DrawRectangleOnImage();
            }
        }

        // 触发PictureBox重绘
        private void DrawRectangleOnImage()
        {
            pictureBox1.Invalidate(); // 触发Paint事件
        }

        // PictureBox绘制事件，在控件表面绘制裁剪框
        private void PictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (currentRect.Width > 0 && currentRect.Height > 0 && originalImage != null)
            {
                // 计算缩放后的矩形，考虑缩放比例和偏移量
                Rectangle scaledRect = new Rectangle(
                    (int)(currentRect.X * imageScale) + imageOffsetX,
                    (int)(currentRect.Y * imageScale) + imageOffsetY,
                    (int)(currentRect.Width * imageScale),
                    (int)(currentRect.Height * imageScale)
                );

                // 创建半透明的填充矩形
                using (Brush brush = new SolidBrush(Color.FromArgb(50, Color.White)))
                {
                    e.Graphics.FillRectangle(brush, scaledRect);
                }

                // 绘制2像素的矩形边框
                using (Pen pen = new Pen(Color.Red, 2))
                {
                    e.Graphics.DrawRectangle(pen, scaledRect);
                }
            }
        }

        // 重置矩形
        private void ResetRectangle()
        {
            currentRect = Rectangle.Empty;
            rectX = 0;
            rectY = 0;
            rectWidth = 0;
            rectHeight = 0;
            ResetTextBoxes();
        }

        // 重置文本框
        private void ResetTextBoxes()
        {
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
        }

        // 加载图片文件到ListView
        private void LoadImageFiles(string folderPath)
        {
            listView1.Items.Clear();
            imageFiles.Clear();

            try
            {
                // 获取文件夹中的所有JPG文件
                //string[] files = Directory.GetFiles(folderPath, "*.jpg|*.bmp|*.png", SearchOption.TopDirectoryOnly);
                // 定义允许的扩展名（不含通配符*）
                HashSet<string> allowedExtensions = new HashSet<string> { ".jpg", ".bmp", ".png" };

                // 获取所有文件，再筛选扩展名
                string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.TopDirectoryOnly)
                    .Where(file => allowedExtensions.Contains(Path.GetExtension(file).ToLower())) // 忽略大小写
                    .ToArray();
                foreach (string file in files)
                {
                    string fileName = Path.GetFileName(file);
                    ListViewItem item = new ListViewItem(fileName);
                    item.SubItems.Add(file);
                    item.SubItems.Add("未处理");
                    item.SubItems.Add("");
                    listView1.Items.Add(item);
                    imageFiles.Add(file);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载图片文件失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 更新ListView项状态
        private void UpdateListViewItem(string filePath, string status, string param)
        {
            foreach (ListViewItem item in listView1.Items)
            {
                if (item.SubItems[1].Text == filePath)
                {
                    item.SubItems[2].Text = status;
                    item.SubItems[3].Text = param;
                    break;
                }
            }
        }
    }
}